from time import sleep, time
# import cv2 as cv
from cv2 import imread, cvtColor, matchTemplate, COLOR_RGB2BGR, TM_CCOEFF_NORMED,imdecode
import numpy as np
from pyperclip import copy
# import pyautogui as pg
from pyautogui import click, hotkey, press
from numpy import asanyarray
from PIL import ImageGrab, ImageDraw
from copy import deepcopy
from lib.template import Template
from lib.tools.myfaker import MyFaker
import os


class Execute:

    def __init__(self, test_data:list, test_name:str):
        self.step_number = []
        self.running_data = []
        self.test_name = test_name.split('\\')[-1].split('.')[0]
        self.test_data = deepcopy(test_data)
        self.result = []
        self.folder = f"{int(time())}_{self.test_name}"
        if not os.path.exists(f"tmp/{self.folder}"):
            os.makedirs(f"tmp/{self.folder}")

    def run(self):
        try:
            self.deal_data()
            test_index = 0
            isEnd = False
            while True:
                for step in self.running_data:
                    im1 = ImageGrab.grab()
                    self.img_isExist(im1)
                    start_img = f"tmp/{self.folder}/pre_{str(time()).strip('.')}.png"
                    draw = ImageDraw.Draw(im1)
                    step_res = None
                    if step[0] == 'click':
                        draw.ellipse([step[1]-30,step[2]-30,step[1]+30,step[2]+30],outline="red",width=5)
                        click(step[1],step[2],clicks=step[3])
                        step_res = f"在{str((step[1],step[2]))}处click {step[3]}次"
                    elif step[0] == 'wait':
                        sleep(int(step[1]))
                        step_res = f"wait {step[1]} s"
                    elif step[0] == 'find':
                        # [['find', [665, 224, 803, 265], [0, [0, 'tmp/contrast1626686494.png'], 0]]]
                        draw.rectangle(step[1],outline='red',width=5)
                        rs = self.location_by_image(step[2][1][1], step[1], step[2][2])
                        step_res = "和预期结果符合" if rs else "未发现预期结果"
                        if not rs:
                            isEnd = True

                    elif step[0] == 'input':
                        draw.ellipse([step[1] - 30, step[2] - 30, step[1] + 30, step[2] + 30], outline="red", width=5)
                        if step[3][0] == 3:
                            self.input_mode(step[3][0], step[3][1])
                            step_res = f"在{str((step[1], step[2]))}处按下 {str(step[3][1])}"
                        elif step[3][0] == 2:
                            click(step[1], step[2])  # 确定焦点
                            self.input_mode(step[3][0], step[3][1])
                            step_res = f"在{str((step[1], step[2]))}处生成 {str(step[3][1])}"
                        elif step[3][0] == 0:
                            click(step[1], step[2])  # 确定焦点
                            test_index = self.running_data.index(step) if self.step_number[test_index] == 0 else test_index
                            if test_index == self.running_data.index(step):
                                if self.step_number[test_index] > 0:
                                    self.step_number[test_index] -= 1
                                    self.input_mode(step[3][0], step[3][1][self.step_number[test_index]])
                                    step_res = f"在{str((step[1], step[2]))} 处输入 {step[3][1][self.step_number[test_index]]}"
                                else:
                                    self.input_mode(step[3][0], step[3][1][0])
                                    step_res = f"在{str((step[1], step[2]))} 处输入 {step[3][1][0]}"
                            else:
                                self.input_mode(step[3][0], step[3][1][0])
                                step_res = f"在{str((step[1], step[2]))} 处输入 {step[3][1][0]}"
                    im2 = ImageGrab.grab()
                    self.img_isExist(im2)
                    end_img = f"tmp/{self.folder}/after_{str(time()).strip('.')}.png"
                    im1.save(start_img)
                    im2.save(end_img)
                    self.result.append([step[0], step_res, start_img, end_img])
                    if isEnd:
                        step_res = 'failed'
                    if step_res:
                        yield step_res

                    sleep(1)
                if sum(self.step_number) == 0:
                    break
        except Exception as e:
            print(e)

    @staticmethod
    def img_isExist(img):
        while not img:
            sleep(0.1)

    def result_to_html(self):
        temp = Template(self.result, self.test_name)
        temp.html_to_file(f"tmp/{self.folder}/result.html")

    @staticmethod
    def input_mode(input_type:int, input_content):
        if input_type == 0:
            copy(input_content)
            hotkey('ctrl','v')
        elif input_type == 2:
            myfaker = MyFaker()
            fun = myfaker.call_funtion(input_content[0])
            if len(input_content) == 2:
                # copy(str(fun(eval(input_content[1]))))
                copy(str(eval(f"fun({input_content[1]})")))
            else:
                copy(str(fun()))
            hotkey('ctrl', 'v')
        elif input_type == 3 :
            if len(input_content) > 1:
                hotkey(*input_content)
            else:
                press(input_content)

    def deal_data(self):
        for step in self.test_data:
            if step[0] == 'click' or step[0] == 'wait':
                self.step_number.append(0)
                self.running_data.append(step)
            elif step[0] == 'input':
                data_list = step[3][1].split(';')
                if step[3][0] == 0:
                    self.step_number.append(len(data_list))
                    step[3][1] = data_list
                    self.running_data.append(step)
                elif step[3][0] == 1:
                    pass
                elif step[3][0] == 2:
                    step[3][1] = step[3][1].split(':')
                    self.step_number.append(0)
                    self.running_data.append(step)
                elif step[3][0] == 3:
                    step[3][1] = step[3][1].split('+')
                    self.step_number.append(0)
                    self.running_data.append(step)
                else:
                    pass
            elif step[0] == 'find':
                # x, y, a, b = step[1]
                # step[1] = [x, y, a-x, b-y]
                self.step_number.append(0)
                self.running_data.append(step)

    @staticmethod
    def location_by_image(image, region=None, minSearchTime=0):
        # im1 = imread(image)
        im1 = imdecode(np.fromfile(image,np.uint8),-1)
        degree = 0.99
        start = time()
        while True:
            screen = asanyarray(ImageGrab.grab(tuple(region)))
            im2 = cvtColor(screen, COLOR_RGB2BGR)
            retVal = matchTemplate(im1, im2, TM_CCOEFF_NORMED)
            if retVal.max() > degree or time() - start > minSearchTime:
                print(retVal.max())
                return True if retVal.max() > degree else False

if __name__ == '__main__':
    res = Execute.location_by_image(r'E:\workspace\python3\NewTest\tmp/登陆/contrast1629253369.png', [0, 125, 353, 207])
    print(res)
